package cn.lianyutiantang.utils;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.io.FileUtils;
import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.ParseException;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.entity.mime.HttpMultipartMode;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.entity.mime.content.FileBody;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.CharsetUtils;
import org.apache.http.util.EntityUtils;

import java.io.*;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.*;

/**
 * @data20160229
 * @author zhengjingli
 * 尝试一下用httpclient来封装一下微信的各种接口 
 */
public class HttpClientUtil {
	
	/**
	 * @data 20160229
	 * @author zhengjingli
	 * @param requestUrl 输出get的url和参数的拼装
	 * @return JSONObject
	 * httpclient的get方法可以调用
	 */
	public static JSONObject httpClinetGetFunction(String requestUrl){
		JSONObject jsonObject = null;
		String resposecontent = null;
		CloseableHttpClient client = null;
		CloseableHttpResponse resp = null;
		try {
			client = HttpClients.createDefault();
			URL url = new URL(requestUrl);
			URI uri =null;
			try {
			 uri = new URI(url.getProtocol(), url.getHost(), url.getPath(), url.getQuery(), null);
			} catch (URISyntaxException e) {
				e.printStackTrace();
			}
			HttpGet get = new HttpGet(uri);
			resp = client.execute(get);
			int statusCode = resp.getStatusLine().getStatusCode();
			if(statusCode>=200&&statusCode<300) {
				HttpEntity entity = resp.getEntity();
				if(entity!=null){
					resposecontent = EntityUtils.toString(entity, "utf-8");
					jsonObject = JSONObject.parseObject(resposecontent);
				}
			}
		} catch (ClientProtocolException e) {
			e.printStackTrace();
		} catch (ParseException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				if(resp!=null) resp.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
			try {
				if(client!=null) client.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return jsonObject;
	}


	/**
	 * @data 20160229
	 * @author zhengjingli
	 * @param requestUrl 输出get的url和参数的拼装
	 * @return String
	 * httpclient的get方法可以调用
	 */
	public static String httpClinetGetFunctionRetrunString(String requestUrl){
		String resposecontent = null;
		CloseableHttpClient client = null;
		CloseableHttpResponse resp = null;
		try {
			client = HttpClients.createDefault();
			URL url = new URL(requestUrl);
			URI uri =null;
			try {
				uri = new URI(url.getProtocol(), url.getHost(), url.getPath(), url.getQuery(), null);
			} catch (URISyntaxException e) {
				e.printStackTrace();
			}
			HttpGet get = new HttpGet(uri);
			resp = client.execute(get);
			int statusCode = resp.getStatusLine().getStatusCode();
			if(statusCode>=200&&statusCode<300) {
				HttpEntity entity = resp.getEntity();
				if(entity!=null){
					resposecontent = EntityUtils.toString(entity, "utf-8");
					//jsonObject = JSONObject.fromObject(resposecontent);
				}
			}
		} catch (ClientProtocolException e) {
			e.printStackTrace();
		} catch (ParseException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				if(resp!=null) resp.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
			try {
				if(client!=null) client.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return resposecontent;
	}
	
	
	/**
	 * @data 20160229
	 * @author zhengjingli
	 * @param requestUrl Post请求的url地址
	 * @param outputStr  要发送的参数
	 * @return JSONObject
	 * httpclient的POST方法可以调用
	 */
	public static JSONObject httpClinetPostFunction(String requestUrl, String outputStr){
		JSONObject jsonObject = null;
		String resposecontent = null;
		CloseableHttpClient client = null;
		CloseableHttpResponse resp = null;
		try {
			client = HttpClients.createDefault();
			URL url = new URL(requestUrl);
			URI uri =null;
			try {
			 uri = new URI(url.getProtocol(), url.getHost(), url.getPath(), url.getQuery(), null);
			} catch (URISyntaxException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			//HttpPost post = new HttpPost(requestUrl);
			HttpPost post = new HttpPost(uri);
			post.addHeader("Content-type","application/json");
			StringEntity entity = new StringEntity(outputStr, ContentType.create("application/json", "UTF-8"));
			post.setEntity(entity);
			//设置请求超时
			RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(4000).setConnectTimeout(4000).build();//设置请求和传输超时时间
			post.setConfig(requestConfig);
			resp = client.execute(post);
			int statusCode = resp.getStatusLine().getStatusCode();
			if(statusCode>=200&&statusCode<300) {
				 resposecontent = EntityUtils.toString(resp.getEntity(), "utf-8");
				if(resposecontent!=null&&!resposecontent.equals("")){
					jsonObject = JSONObject.parseObject(resposecontent);
				}else{
					System.out.println("调用接口："+requestUrl+"，请求参数："+outputStr+"。返回结果集为空！！");
				}

			}
		} catch (ClientProtocolException e) {
			e.printStackTrace();
		} catch (ParseException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				if(resp!=null) resp.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
			try {
				if(client!=null) client.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return jsonObject;
	}
	/**
	 * @data 20160229
	 * @author zhengjingli
	 * @param requestUrl Post请求的url地址
	 * @param outputStr  要发送的参数
	 * @return JSONObject
	 * httpclient的POST方法可以调用
	 */
	public static JSONObject httpClinetPostFunction(String requestUrl, String outputStr, int timeout){
		JSONObject jsonObject = null;
		String resposecontent = null;
		CloseableHttpClient client = null;
		CloseableHttpResponse resp = null;
		try {
			client = HttpClients.createDefault();
			URL url = new URL(requestUrl);
			URI uri =null;
			try {
				uri = new URI(url.getProtocol(), url.getHost(), url.getPath(), url.getQuery(), null);
			} catch (URISyntaxException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			//HttpPost post = new HttpPost(requestUrl);
			HttpPost post = new HttpPost(uri);
			post.addHeader("Content-type","application/json");
			StringEntity entity = new StringEntity(outputStr, ContentType.create("application/json", "UTF-8"));
			post.setEntity(entity);
			//设置请求超时
			RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(timeout).setConnectTimeout(timeout).build();//设置请求和传输超时时间
			post.setConfig(requestConfig);
			resp = client.execute(post);
			int statusCode = resp.getStatusLine().getStatusCode();
			if(statusCode>=200&&statusCode<300) {
				resposecontent = EntityUtils.toString(resp.getEntity(), "utf-8");
				if(resposecontent!=null&&!resposecontent.equals("")){
					jsonObject = JSONObject.parseObject(resposecontent);
				}else{
					System.out.println("调用接口："+requestUrl+"，请求参数："+outputStr+"。返回结果集为空！！");
				}

			}
		} catch (ClientProtocolException e) {
			e.printStackTrace();
		} catch (ParseException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				if(resp!=null) resp.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
			try {
				if(client!=null) client.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return jsonObject;
	}
	/**
	 * @data 20160229
	 * @author zhengjingli
	 * @param requestUrl Post请求的url地址
	 * @param outputStr  要发送的参数
	 * @return JSONObject
	 * httpclient的POST方法可以调用
	 */
	public static String httpClinetPostFunctionReturnString(String requestUrl, String outputStr){
		String resposecontent = null;
		CloseableHttpClient client = null;
		CloseableHttpResponse resp = null;
		try {
			client = HttpClients.createDefault();
			URL url = new URL(requestUrl);
			URI uri =null;
			try {
				uri = new URI(url.getProtocol(), url.getHost(), url.getPath(), url.getQuery(), null);
			} catch (URISyntaxException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			//HttpPost post = new HttpPost(requestUrl);
			HttpPost post = new HttpPost(uri);
			post.addHeader("Content-type","application/json");
			StringEntity entity = new StringEntity(outputStr, ContentType.create("application/json", "UTF-8"));
			post.setEntity(entity);
			//设置请求超时
			RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(4000).setConnectTimeout(4000).build();//设置请求和传输超时时间
			post.setConfig(requestConfig);
			resp = client.execute(post);
			int statusCode = resp.getStatusLine().getStatusCode();
			if(statusCode>=200&&statusCode<300) {
				resposecontent = EntityUtils.toString(resp.getEntity(), "utf-8");
			}
		} catch (ClientProtocolException e) {
			e.printStackTrace();
		} catch (ParseException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				if(resp!=null) resp.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
			try {
				if(client!=null) client.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return resposecontent;
	}
	//用apache接口实现http的post提交数据
	public static String sendHttpClientPost(String path,
                                            Map<String, String> params, String encode) {
		List<NameValuePair> list = new ArrayList<NameValuePair>();
		if (params != null && !params.isEmpty()) {
			for (Map.Entry<String, String> entry : params.entrySet()) {
				list.add(new BasicNameValuePair(entry.getKey(), entry
						.getValue()));
			}
		}
		try {
			// 实现将请求的参数封装到表单中，即请求体中
			UrlEncodedFormEntity entity = new UrlEncodedFormEntity(list, encode);
			// 使用post方式提交数据
			HttpPost httpPost = new HttpPost(path);
			httpPost.setEntity(entity);
			// 执行post请求，并获取服务器端的响应HttpResponse
			CloseableHttpClient client=null;
			client = HttpClients.createDefault();
			CloseableHttpResponse httpResponse = null;
			httpResponse = client.execute(httpPost);
			//HttpResponse httpResponse = client.execute(httpPost);

			//获取服务器端返回的状态码和输入流，将输入流转换成字符串
			if (httpResponse.getStatusLine().getStatusCode() == 200) {
				InputStream inputStream = httpResponse.getEntity().getContent();
				return changeInputStream(inputStream, encode);
			}
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		} catch (ClientProtocolException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return "";

	}

	/*
	 * // 把从输入流InputStream按指定编码格式encode变成字符串String
	 */
	public static String changeInputStream(InputStream inputStream,
                                           String encode) {

		// ByteArrayOutputStream 一般叫做内存流
		ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
		byte[] data = new byte[1024];
		int len = 0;
		String result = "";
		if (inputStream != null) {

			try {
				while ((len = inputStream.read(data)) != -1) {
					byteArrayOutputStream.write(data, 0, len);

				}
				result = new String(byteArrayOutputStream.toByteArray(), encode);

			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}

		}

		return result;
	}


	/**
	 * @data 20160229
	 * @author 郑景立
	 * @param url   上传的URL地址
	 * @param path  上传的路径
	 * @return
	 */
	public static JSONObject postMedia(String url, String path) {
		CloseableHttpClient client = null;
		CloseableHttpResponse resp = null;
		try {
			client = HttpClients.createDefault();
			/*
			String url = WeixinFinalValue.POST_MEDIA;
			url = url.replace("ACCESS_TOKEN", RefreshAccessTokenTask.at);
			url = url.replace("TYPE", type);*/
			HttpPost post = new HttpPost(url);
			FileBody fb = new FileBody(new File(path));
			HttpEntity reqEntity = MultipartEntityBuilder
						.create().addPart("media", fb).build();
			post.setEntity(reqEntity);
			resp = client.execute(post);
			int sc = resp.getStatusLine().getStatusCode();
			if(sc>=200&&sc<300) {
				String json = EntityUtils.toString(resp.getEntity());
				return JSONObject.parseObject(json);
			}
		} catch (ClientProtocolException e) {
			e.printStackTrace();
		} catch (ParseException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				if(client!=null) client.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
			try {
				if(resp!=null) resp.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return null;
	}
	/**
	 * @data 20160229
	 * @author 郑景立
	 * @param url   要下载文件的URL地址
	 * @param mediaId  媒体文件上传时候成功时返回的媒体ID
	 * @param f  存放的文件
	 */
	public static void getMedia(String url, String mediaId, File f) {
		CloseableHttpClient client = null;
		CloseableHttpResponse resp = null;
		
		try {
			client = HttpClients.createDefault();
			/*String url = WeixinFinalValue.GET_MEDIA;
			url = url.replace("ACCESS_TOKEN", RefreshAccessTokenTask.at);
			url = url.replace("MEDIA_ID", mediaId);*/
			HttpGet get = new HttpGet(url);
			resp = client.execute(get);
			int sc = resp.getStatusLine().getStatusCode();
			if(sc>=200&&sc<300) {
				InputStream is = resp.getEntity().getContent();
				FileUtils.copyInputStreamToFile(is, f);
			}
		} catch (ClientProtocolException e) {
			e.printStackTrace();
		} catch (ParseException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				if(client!=null) client.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
			try {
				if(resp!=null) resp.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

	//把JSONObject转换成键值对形式返回
	public static HashMap<String, Object> transfer(JSONObject jsonObject){
		Map data = new HashMap<String, Object>();
		data=JSON.parseObject(JSON.toJSONString(jsonObject),Map.class);
		return (HashMap<String, Object>) data;
	}


	//给特定的微信好发送客服消息
		/*
		 	当用户主动发消息给公众号的时候（包括发送信息、点击自定义菜单、订阅事件、扫描二维码事件、支付成功事件、用户维权），
		 	微信将会把消息数据推送给开发者，开发者在一段时间内（目前修改为48小时）可以调用客服消息接口，通过POST一个JSON数据包来发送消息给普通用户，
		 	在48小时内不限制发送次数。此接口主要用于客服等有人工消息处理环节的功能，方便开发者为用户提供更加优质的服务。
		 	调用URL： http://1m4529991g.51mypc.cn/springmvc/weixin/sendMsgToCustom?touser=oMnVmvy-vjq-raLccRkEa2FFC3mE&content=zhengjingli
		 */

	/**
	 *
	 * @param content  发送内容
	 * @param touser  接受这openid
	 * @return
	 */
	public static HashMap<String, Object> sendMsgToCustom(String content, String touser){
		//String url="https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token="+ TokenThread.accessToken.getToken();
		String url="https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token="/*+ TokenThread.accessToken.getToken()*/;
		Map map = new HashMap();
		map.put("touser", touser);
		map.put("msgtype", "text");
		Map testMap = new HashMap();
		testMap.put("content", content);
		map.put("text", testMap);
		String outputStr = JSONObject.toJSONString(map);
		System.out.println("outPutStr请求JSON是："+outputStr);
		JSONObject jsonObject = HttpClientUtil.httpClinetPostFunction(url, outputStr);
		System.out.println("客服消息发送接口："+jsonObject.toString());
		return transfer(jsonObject);
	}

	public static void main(String[] args) {
		String path = "http://106.ihuyi.com/webservice/sms.php?method=Submit";
		Map<String, String> params = new HashMap<String, String>();
		params.put("account","cf_gzyn5180");
		//params.put("password", "01354329d91c6ce2829e8cd927101e70");
		params.put("password", "904c421e73360a122fc231d1731b3b91");
		params.put("mobile", "13527827690");
		params.put("content","您的验证码是：6666。请不要把验证码泄露给其他人。");
		params.put("time", null);
		params.put("format", "json");
		String result = sendHttpClientPost(path, params, "utf-8");
		System.out.println("-result->>" + result);
		JSONObject jsonObject = JSONObject.parseObject(result);
		System.out.println(jsonObject.get("code")+"||"+jsonObject.get("msg")+"||"+jsonObject.get("smsid"));

	}
    //调用文件服务器接口上传文件
	public static JSONObject uploadFile(File file, String url) {
		CloseableHttpClient client = null;
		CloseableHttpResponse resp = null;
		try {
			client = HttpClients.createDefault();
			HttpPost post = new HttpPost(url);
			// 以浏览器兼容模式运行，防止文件名乱码。
			FileBody bin = new FileBody(file);
			HttpEntity reqEntity = MultipartEntityBuilder.create()
					.setMode(HttpMultipartMode.BROWSER_COMPATIBLE)
					.addPart("uploadFile", bin)
					.setCharset(CharsetUtils.get("UTF-8")).build();
			//设置请求超时
			RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(4000).setConnectTimeout(4000).build();//设置请求和传输超时时间
			post.setConfig(requestConfig);

			post.setEntity(reqEntity);
			resp = client.execute(post);
			int sc = resp.getStatusLine().getStatusCode();
			if(sc>=200&&sc<300) {
				String json = EntityUtils.toString(resp.getEntity());
				return JSONObject.parseObject(json);
			}
		} catch (ClientProtocolException e) {
			e.printStackTrace();
		} catch (ParseException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				if(client!=null) client.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
			try {
				if(resp!=null) resp.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return null;
	}


}
